/**
 * @file post_process.cc
 * @author your name (you@domain.com)
 * @brief 1号线程，根据检测结果画框，同时响应3号线程的信号量，报警和保存图像
 * @version 0.1
 * @date 2023-2-02
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "module_post_process.h"
#include <unistd.h>
#include <stdio.h>
#include <mutex>
#include <iostream>
#include <queue>
#include <utility>
#include <string>
#include <sys/time.h>
#include "object_detect.h"
#include "opencv2/opencv.hpp"
extern "C"{
    #include "rk_init.h"
    #include "rkmedia_api.h"
    #include "rk_list_process.h"
    #include "rk_nv12_to_rgb.h"
}

extern int g_flag_run;
extern rknn_list *rknn_list_;
// extern int flag_triggle;
extern std::mutex flag_triggle_mutex;
extern struct demo_cfg cfg;

extern std::mutex flag_triggle_mutex;        
extern std::queue<std::pair<std::string, cv::Mat>> queueSaveimg_640;

static void sig_proc(int signo) {
  printf("signal %d\n", signo);
}
/*-------------------------------------------
                线程1:图像保存
-------------------------------------------*/

void *module_post_process(void *arg)
{
    uint8_t cpu_id = 1;
    //线程对cpu亲和性设定   
    cpu_set_t mask;
    CPU_ZERO(&mask);
    CPU_SET(cpu_id, &mask);
    printf("Bind module_post_process thread to CPU %d\n", cpu_id);
    
    signal(SIGSEGV, sig_proc);
    while (g_flag_run) {
        MEDIA_BUFFER buffer;
        //进行画框
        buffer = RK_MPI_SYS_GetMediaBuffer(
            RK_ID_VI, cfg.session_cfg[DRAW_INDEX].stViChn.s32ChnId, -1);
        if (!buffer)
            continue;
        if (rknn_list_size(rknn_list_)) {
            detect_result_group_t detect_result_group_tmp;
            long time_before;
            rknn_list_pop(rknn_list_, &time_before, &detect_result_group_tmp);
            // printf("time interval is %ld\n", getCurrentTimeMsec() - time_before);       // Todo:计算和上一个线程流水线时间间隔的

            for (int j = 0; j < detect_result_group_tmp.count; j++) {
            int x = detect_result_group_tmp.results[j].box.left;
            int y = detect_result_group_tmp.results[j].box.top;
            int w = (detect_result_group_tmp.results[j].box.right -
                        detect_result_group_tmp.results[j].box.left);
            int h = (detect_result_group_tmp.results[j].box.bottom -
                        detect_result_group_tmp.results[j].box.top);
            if (x < 0)
                x = 0;
            if (y < 0)
                y = 0;
            while ((uint32_t)(x + w) >= cfg.session_cfg[DRAW_INDEX].u32Width) {
                w -= 16;
            }
            while ((uint32_t)(y + h) >= cfg.session_cfg[DRAW_INDEX].u32Height) {
                h -= 16;
            }
            printf("border=(%d %d %d %d)\n", x, y, w, h);
            nv12_border((char *)RK_MPI_MB_GetPtr(buffer),
                        cfg.session_cfg[DRAW_INDEX].u32Width,
                        cfg.session_cfg[DRAW_INDEX].u32Height, x, y, w, h, 0, 0,
                        255);
            }
        }
        // send from VI to VENC
        RK_MPI_SYS_SendMediaBuffer(
            RK_ID_VENC, cfg.session_cfg[DRAW_INDEX].stVenChn.s32ChnId, buffer);     //Todo:这里用send，而不是绑定，说明数据都是一帧一帧经过这个模块再发送出去的
        RK_MPI_MB_ReleaseBuffer(buffer);

        //判断生消模型队列是否为空,每次保存一帧图像
        if(!queueSaveimg_640.empty())
        {
            //报警、保存视频帧
            flag_triggle_mutex.lock();
            std::pair<std::string, cv::Mat> img_info = queueSaveimg_640.front();
            queueSaveimg_640.pop();
            std::string pic_name = img_info.first;
            flag_triggle_mutex.unlock();
            cv::Mat pic = img_info.second;
            cv::imwrite(pic_name,pic);
            printf("%s 保存完毕\n", pic_name.c_str());
        }
    }
}